﻿function callClientFunction ( client, funcname, ... )
    local arg = { ... }
    if ( arg [ 1 ] ) then
        for key, value in next, arg do
            if ( type ( value ) == "number" ) then arg [ key ] = tostring ( value ) end
        end
    end
    -- If the clientside event handler is not in the same resource, replace 'resourceRoot' with the appropriate element
    triggerClientEvent ( client, "onServerCallsClientFunction", resourceRoot, funcname, unpack ( arg or {} ) )
end

function callServerFunction ( funcname, ... )
    local arg = { ... }
    if ( arg [ 1 ] ) then
        for key, value in next, arg do arg [ key ] = tonumber ( value ) or value end
    end
    loadstring ( "return " .. funcname ) () ( unpack ( arg ) )
end
addEvent ( "onClientCallsServerFunction", true )
addEventHandler ( "onClientCallsServerFunction", resourceRoot , callServerFunction )

-- format of data
-- creator = { string elementType1, string elementType2, ... }
-- elementType* = { int first ID, int last ID, { exception1, exception2, ... } }
creatorTable = { ped = { 0, 288, { 3, 4, 5, 6, 8, 42, 65, 74, 86, 119, 149, 208, 239, 273 } }, vehicle = { 400, 611, { 570 } }, weapon = { 321, 373, { 332, 340, 345, 354, 370 } }, object = { 615, 18630, {} } }
function creatorError ( player )
	outputChatBox ( "Invalid #9696ffID/vehicle name#6464ff passed or creation failed!", player, 100, 100, 255, true )
end
function VAMcreate ( player, vehicle, id )
	if tonumber ( id ) then
		id = tonumber ( id )
		local elementType
		for theType, values in pairs ( creatorTable ) do
			if id >= values [ 1 ] and id <= values [ 2 ] then
				for k, v in ipairs ( values [ 3 ] ) do
					if id == v then
						creatorError ( player )
						return
					end
				end
				elementType = theType
				break
			end
		end
		if elementType then
			local element
			if elementType == "ped" then
				element = createPed ( id, 0, 0, 0 )
			elseif elementType == "vehicle" then
				element = createVehicle ( id, 0, 0, 0 )
			elseif elementType == "weapon" or "object" then
				element = createObject ( id, 0, 0, 0 )
			end
			if attachElements ( element, vehicle ) then
				outputChatBox ( "Created the #9696ff" .. elementType .. "#6464ff using ID #9696ff" .. id .. "#6464ff successfully!", player, 100, 100, 255, true )
				setElementData ( element, "createdByVAM", true )
				callClientFunction ( player, "g_GridUpdate" )
				return
			else
				destroyElement ( element )
			end
		end
		creatorError ( player )
	elseif tostring ( id ) then
		local matches = {}
		for i = 400, 611 do
			if i ~= 570 then
				if string.find ( string.lower ( getVehicleNameFromModel ( i ) ), id ) then
					table.insert ( matches, i )
				end
			end
		end
		if #matches == 0 then
			outputChatBox ( "Vehicle name #9696ff" .. id .. "#6464ff matches no vehicles!", player, 100, 100, 255, true )
		elseif #matches == 1 then
			local model = matches [ 1 ]
			local element = createVehicle ( model, 0, 0, 0 )
			if attachElements ( element, vehicle ) then
				outputChatBox ( "Created the #9696ff" .. getVehicleNameFromModel ( model ) .. "#6464ff using vehicle name #9696ff" .. id .. "#6464ff successfully!", player, 100, 100, 255, true )
				setElementData ( element, "createdByVAM", true )
				callClientFunction ( player, "g_GridUpdate" )
				return
			else
				destroyElement ( element )
			end
		elseif #matches > 1 then
			outputChatBox ( "Vehicle name #9696ff" .. id .. "#6464ff matches #9696ff" .. #matches .. "#6464ff vehicles!", player, 100, 100, 255, true )
		end
	else
		creatorError ( player )
	end
end

function VAMdestroy ( player, element, elementName )
	if destroyElement ( element ) then
		outputChatBox ( "Successfully destroyed #9696ff" .. elementName .. "#6464ff.", player, 100, 100, 255, true )
		callClientFunction ( player, "g_GridUpdate" )
	else
		outputChatBox ( "#9696ff" .. elementName .. "#6464ff could not be destroyed!", player, 100, 100, 255, true )
	end
end

function VAMdetach ( player, element, elementName )
	local boolean = getElementCollisionsEnabled ( element )
	if detachElements ( element ) then
		if not boolean then
			setElementCollisionsEnabled ( element, true )
		end
		outputChatBox ( "Successfully detached #9696ff" .. elementName .. "#6464ff.", player, 100, 100, 255, true )
		callClientFunction ( player, "g_GridUpdate" )
	else
		outputChatBox ( "#9696ff" .. elementName .. "#6464ff could not be detached!", player, 100, 100, 255, true )
	end
end

function VAMvisibilityToggle ( player, element, elementName, alpha )
	if setElementAlpha ( element, alpha ) then
		outputChatBox ( "Successfully changed #9696ff" .. elementName .. "#6464ff's visibility.", player, 100, 100, 255, true )
		callClientFunction ( player, "g_GridUpdate" )
	else
		outputChatBox ( "#9696ff" .. elementName .. "#6464ff's visibility could not be changed!", player, 100, 100, 255, true )
	end
end

boolToText = { [ true ] = "on", [ false ] = "off" }
function VAMcollisionToggle ( player, element, elementName, boolean )
	if setElementCollisionsEnabled ( element, boolean ) then
		outputChatBox ( "Successfully changed #9696ff" .. elementName .. "#6464ff's collisions #9696ff" .. boolToText [ boolean ] .. "#6464ff.", player, 100, 100, 255, true )
		callClientFunction ( player, "g_GridUpdate" )
	else
		outputChatBox ( "#9696ff" .. elementName .. "#6464ff's collisions could not be changed!", player, 100, 100, 255, true )
	end
end

function VAMscale ( player, element, elementName, factor )
	if setObjectScale ( element, factor ) then
		outputChatBox ( "Successfully changed scale of #9696ff" .. elementName .. "#6464ff.", player, 100, 100, 255, true )
		callClientFunction ( player, "g_GridUpdate" )
	else
		outputChatBox ( "#9696ff" .. elementName .. "#6464ff could not be scaled!", player, 100, 100, 255, true )
	end
end

-- weapons

function VAMweaponCreate ( player, vehicle, id )
	local weaponDummy = exports.s_weaps:createWeapon ( id, 0, 0, 0, 0, 0, 0 )
	if weaponDummy then 
		if exports.s_weaps:attachWeaponToElement ( weaponDummy, vehicle ) and exports.s_weaps:setWeaponOwner ( weaponDummy, player ) and setElementData ( weaponDummy, "createdByVAM", true ) then
			outputChatBox ( "Created the #9696ffweapon#6464ff using ID #9696ff" .. id .. "#6464ff successfully!", player, 100, 100, 255, true )
			callClientFunction ( player, "g_GridUpdate" )
			return
		end
	end
	outputChatBox ( "Invalid #9696ffweaponID#6464ff passed or creation failed! Make sure #9696ffs_weaps#6464ff resource is started.", player, 100, 100, 255, true )
end

function VAMweaponOffsetsUpdate ( weaponDummy, vehicle, x, y, z, rx, ry, rz )
	exports.s_weaps:attachWeaponToElement ( weaponDummy, vehicle, x, y, z, rx, ry, rz )
end

function VAMweaponDestroy ( player, weaponDummy, elementName )
	if exports.s_weaps:destroyWeapon ( weaponDummy ) then
		outputChatBox ( "Successfully destroyed #9696ff" .. elementName .. "#6464ff.", player, 100, 100, 255, true )
		callClientFunction ( player, "g_GridUpdate" )
	else
		outputChatBox ( "#9696ff" .. elementName .. "#6464ff could not be destroyed!", player, 100, 100, 255, true )
	end
end

function VAMweaponShoot ( weaponDummy, state )
	exports.s_weaps:setWeaponState ( weaponDummy, state )
end

function VAMweaponVisibilityToggle ( player, weaponDummy, elementName, alpha )
	if exports.s_weaps:setWeaponAlpha ( weaponDummy, alpha ) then
		outputChatBox ( "Successfully changed #9696ff" .. elementName .. "#6464ff's visibility.", player, 100, 100, 255, true )
		callClientFunction ( player, "g_GridUpdate" )
	else
		outputChatBox ( "#9696ff" .. elementName .. "#6464ff's visibility could not be changed!", player, 100, 100, 255, true )
	end
end

function VAMcleanAllVAMcreatedWeapons ()
	for k, weaponDummy in ipairs ( getElementsByType ( "weaponDummy" ) ) do
		if getElementData ( weaponDummy, "createdByVAM" ) then
			exports.s_weaps:destroyWeapon ( weaponDummy )
		end
	end
end
addEventHandler ( "onResourceStop", resourceRoot, VAMcleanAllVAMcreatedWeapons )